// 函数是什么?
// 定义: 具有特定功能的一段独立代码=> 
// 复用已有的功能=>封装: 复用 +  独立
// 符合函数式编程=>

function fn1() {
  console.log('fn1---------')
}

function fn2() {
  console.log('fn2---------')
}

// fn3的功能是log1 log2
// 1.0  不符合独立的特点 依赖关系
// function fn3() {
//     // console.log('fn1---------')
//     // console.log('fn2---------')
//   fn1()
//   fn2()
// }
// 2.0 不灵活=> 使用者
// function fn3(FN1,FN2) {
//     // console.log('fn1---------')
//     // console.log('fn2---------')
//   FN1()
//   FN2()
// }
// fn3(fn1,fn2)

// 3.0 => 解决了形参数量的问题
// function fn3(...fns) {
//   //   console.log(fns)

//   fns.forEach((fn) => {
//     fn()
//   })
//   // arguments
//   // ...rest
// }
// fn3(fn1, 200)

// 4.0 形参类型的问题

function fn3(...fns) {
  fns.forEach((fn) => {
    if (typeof fn === 'function') {
      fn()
    } else {
      console.log('非fn')
    }
  })
  // arguments
  // ...rest
}
fn3(fn1, 200)

// 封装函数合理且严谨
// 1. 复用=>功能复用
// 2. 独立=> 不依赖外部数据
// 3. 形参类型监测=> 内部代码不出问题
// ..........
// ..........

// ==========>  函数式编程概念  ===========> react

// function fn(a) {}
// 高阶函数:
// 语法: 函数A的形参or返回值是函数B

// 1. 回调函数: 异步拿结果
// 形式上的理解: 函数A的形参是函数B
// 本质: 函数A里面复用了函数B的功能

// 2.闭包: 全局变量被污染=>不想声明全局变量,还想做到和全局变量一样的效果

// 形式上的理解: 函数A的返回值是函数B
// 本质: 函数的作用域链
// function  fn4() {
//     return function () {
//     }
// }
// fn4()()

// 3. 函数柯里化=> 让函数延迟执行!!!!!!!!=> 分阶段的为函数做准备工作

// 特点: 让函数的形参分阶段的进行准备===> 让函数延迟执行!!!!!!!!
// 反例: 函数调用时,不能保证所有实参数据都准备好
// function fnsum(a) {
//   return (b) => {
//     return (c) => {
//       return (d) => {
//         return (e) => {
//           return a + b + c + d + e
//         }
//       }
//     }
//   }
// }

// 希望下面代码能运行
// sum(a, b, c, d, e) /// ?????????????

// let result = fnsum(1)
// 100业务代码 =>  数据2
// let fnnew = result(1)(2)
// 200业务代码 =>  数据3
// fnnew(3)
// let fn1 = fnsum(1)
// fn2 = fn1(2)
// fn3 = fn2(3)
// fn4 = fn3(4)
// let result = fn4(5)

console.log(result)
